#!/usr/bin/env python3
# coding:utf-8

import asyncio
import aiomqtt

Config = {
    "ip": "192.168.111.17",
    "port": 1883,
    "username": "test",
    "password": "test",
    "ca_file": "",
}


class MqttClient:
    def __init__(self, config):
        self.config = config
        self.mqttc = None
        self.event = asyncio.Event()

    async def loop_run(self):
        ip = self.config["ip"]
        port = self.config["port"]
        username = self.config["username"]
        password = self.config["password"]
        while True:
            try:
                async with aiomqtt.Client(
                    ip, port, username=username, password=password, timeout=5, keepalive=6
                ) as client:
                    self.mqttc = client
                    await client.subscribe("test/topic")
                    await client.subscribe("test/abc")
                    self.event.set()  # 唤醒全部 publish
                    print("mqtt 连接成功")
                    async for msg in client.messages:
                        print("recv: ", msg.topic, msg.payload)
            except aiomqtt.MqttError as e:
                print(f"MQTT error: {e}")
            except asyncio.CancelledError:
                print("MQTT Operation was cancelled")
            except Exception as e:
                print(f"MQTT An unexpected error occurred: {e}")
            await asyncio.sleep(8)

    async def timer_publish(self):
        await self.event.wait()
        self.event.clear()
        count: int = 0
        while True:
            try:
                await self.mqttc.publish("test/topic", f"hello world {count}")
            except Exception as e:
                print(f"mqtt异常:{e} -->等待重连")
                await self.event.wait()
                self.event.clear()
            count += 1
            await asyncio.sleep(2)


    async def timer_publish_v2(self):
        await self.event.wait()
        self.event.clear()
        count: int = 0
        while True:
            try:
                await self.mqttc.publish("test/abc", f"this is abc {count}")
            except Exception as e:
                print(f"v2 mqtt异常:{e} -->等待重连")
                await self.event.wait()
                self.event.clear()
            count -= 1
            await asyncio.sleep(3)



async def main():
    mqttc = MqttClient(Config)
    await asyncio.gather(
        mqttc.loop_run(),
        mqttc.timer_publish(),
        mqttc.timer_publish_v2(),
    )


if __name__ == "__main__":
    asyncio.run(main())


""" 
测试方法:
1. 断开网卡, 或关闭mqtt服务端
2.self.mqttc.publish 发布者报错, 等待重连

3.恢复网络或mqtt服务端
4.发布者重新连接成功 

"""